package com.ironman.h6b1gw.rest;

import cn.hutool.core.util.HexUtil;
import com.ironman.h6b1gw.tlv.TLVEncoder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.mica.mqtt.codec.MqttQoS;
import org.dromara.mica.mqtt.spring.client.MqttClientTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;

/**
 * 鸿途智能断路器网关
 */
@Slf4j
@RequiredArgsConstructor
@RestController
public class HtGwController {

    final MqttClientTemplate mqttClientTemplate;

    /**
     * 一键合闸
     */
    @GetMapping("/one-click/open")
    public String oneClickOpen(String sequence) {
        int index = Integer.parseInt(sequence, 2);
        // 一键合闸
        byte[] req = TLVEncoder.mergeBytes(
                TLVEncoder.encodeTLV("0392", String.format("%016X", index)),
                TLVEncoder.encodeTLV("0A02", "0400")
        );
        String hexCmd = HexUtil.encodeHexStr(req).toUpperCase();
        log.info("一键合闸 发送指令：{}", hexCmd);
        publish("一键合闸", hexCmd);
        return String.format("%32s", Integer.toBinaryString(index))
                .replace(' ', '0');
    }

    /**
     * 一键分闸
     */
    @GetMapping("/one-click/close")
    public String oneClickClose(String sequence) {
        int index = Integer.parseInt(sequence, 2);
        // 一键分闸
        byte[] req = TLVEncoder.mergeBytes(
                TLVEncoder.encodeTLV("038A", String.format("%016X", index)),
                TLVEncoder.encodeTLV("0A02", "0800")
        );
        String hexCmd = HexUtil.encodeHexStr(req).toUpperCase();
        log.info("一键分闸 发送指令：{}", hexCmd);
        publish("一键分闸", hexCmd);
        return String.format("%32s", Integer.toBinaryString(index))
                .replace(' ', '0');
    }

    /**
     * 顺序合闸
     */
    @GetMapping("/sequence/open")
    public String sequenceOpen(String sequence, @RequestParam(defaultValue = "1000", required = false) int delay) {
        int index = Integer.parseInt(sequence, 2);
        // 顺序合闸
        byte[] req = TLVEncoder.mergeBytes(TLVEncoder.encodeTLV("053C", String.format("%016X", index)),
                TLVEncoder.encodeTLV("0532", String.format("%04X", delay / 10)),
                TLVEncoder.encodeTLV("0A02", "0040")
        );
        String hexCmd = HexUtil.encodeHexStr(req).toUpperCase();
        log.info("顺序合闸 发送指令：{}", hexCmd);
        publish("顺序合闸", hexCmd);
        return String.format("%32s", Integer.toBinaryString(index))
                .replace(' ', '0');
    }

    /**
     * 顺序分闸
     */
    @GetMapping("/sequence/close")
    public String sequenceClose(String sequence, @RequestParam(defaultValue = "1000", required = false) int delay) {
        int index = Integer.parseInt(sequence, 2);
        // 顺序分闸
        byte[] req = TLVEncoder.mergeBytes(TLVEncoder.encodeTLV("0534", String.format("%016X", index)),
                TLVEncoder.encodeTLV("0532", String.format("%04X", delay / 10)),
                TLVEncoder.encodeTLV("0A02", "0080")
        );
        String hexCmd = HexUtil.encodeHexStr(req).toUpperCase();
        publish("顺序分闸", hexCmd);
        return String.format("%32s", Integer.toBinaryString(index))
                .replace(' ', '0');
    }

    private void publish(String opt, String hexCmd) {
        log.info("{} 发送指令：{}", opt, hexCmd);
        mqttClientTemplate.publish("/v1/gw/gw10001332/down_raw", hexCmd.getBytes(StandardCharsets.UTF_8), MqttQoS.QOS1);
    }

    public static void main(String[] args) {
        String sequence = "101";
        int index = Integer.parseInt(sequence, 2);
        String valueHex = String.format("%016X", index);
        System.out.println(valueHex);

        // 一键合闸
        byte[] req = TLVEncoder.mergeBytes(TLVEncoder.encodeTLV("0392", valueHex), TLVEncoder.encodeTLV("0A02", "0400"));
        String hexCmd = HexUtil.encodeHexStr(req).toUpperCase();
        System.out.println(hexCmd);

        String bitNum = String.format("%32s", Integer.toBinaryString(index)).replace(' ', '0');
        System.out.println(bitNum);
    }
}
